home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / minix / libsrc~1.z / libsrc~1 / getcwd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-12-28  |  3.3 KB  |  197 lines

  1. #include "lib.h"
  2.  
  3. /*  getcwd(3)
  4.  *
  5.  *  Author: Terrence W. Holm          Aug. 1988
  6.  *
  7.  *  Directly derived from Adri Koppes' pwd(1).
  8.  */
  9.  
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include <sys/dir.h>
  13. #include <errno.h>
  14.  
  15. #ifndef  NULL
  16. #define  NULL         (char *) 0
  17. #endif
  18.  
  19. #define  O_RDONLY     0
  20. #define  DIRECT_SIZE  ((int)sizeof (struct direct))
  21. #ifndef PATH_MAX
  22. #define  PATH_MAX     127
  23. #endif
  24.  
  25. #ifdef __STDC__
  26. extern char *rindex(_CONST char *, int);
  27. #else
  28. extern char *rindex();
  29. #endif
  30.  
  31. extern int errno;
  32.  
  33.  
  34. char *getcwd( buffer, size )
  35.   char *buffer;
  36.   int   size;
  37.  
  38.   {
  39.   static char path[ PATH_MAX + 1 ];
  40.   struct stat current;
  41.  
  42.   if ( buffer == NULL  ||  size == 0 )
  43.     {
  44.     errno = EINVAL;
  45.     return( NULL );
  46.     }
  47.  
  48.   path[0] = '\0';
  49.  
  50.   /*  Get the inode for the current directory  */
  51.    
  52.   if ( stat( ".", ¤t ) == -1 )
  53.     return( NULL );
  54.  
  55.   if ( (current.st_mode & S_IFMT) != S_IFDIR )
  56.     return( NULL );
  57.  
  58.  
  59.   /*  Run backwards up the directory tree, grabbing     */
  60.   /*  directory names on the way.            */
  61.  
  62.   while (1)
  63.     {
  64.     struct stat parent;
  65.     struct direct d;
  66.     int same_device = 0;
  67.     int found = 0;
  68.     int fd;
  69.  
  70.     /*  Get the inode for the parent directory  */
  71.  
  72.     if ( chdir( ".." ) == -1 )
  73.     return( NULL );
  74.  
  75.     if ( stat( ".", &parent ) == -1 )
  76.     return( NULL );
  77.  
  78.     if ( (parent.st_mode & S_IFMT) != S_IFDIR )
  79.     return( NULL );
  80.  
  81.     if ( current.st_dev == parent.st_dev )
  82.     same_device = 1;
  83.  
  84.  
  85.     /*  At the root, "." is the same as ".."  */
  86.  
  87.     if ( same_device  &&  current.st_ino == parent.st_ino )
  88.     break;
  89.  
  90.  
  91.     /*  Search the parent directory for the current entry  */
  92.  
  93.     if ( (fd = open( ".", O_RDONLY )) == -1 )
  94.     return( NULL );
  95.  
  96.     while ( ! found  &&  read(fd, &d, DIRECT_SIZE) == DIRECT_SIZE )
  97.     {
  98.     if ( same_device )
  99.         {
  100.         if ( current.st_ino == d.d_ino )
  101.         found = 1;
  102.         }
  103.     else
  104.         {
  105.         static char temp_name[ DIRSIZ + 1 ];
  106.         static struct stat dir_entry;
  107.  
  108.         temp_name[0] = '\0';
  109.         strncat( temp_name, d.d_name, DIRSIZ );
  110.  
  111.         if ( stat( temp_name, &dir_entry ) == -1 )
  112.         {
  113.         close( fd );
  114.         return( NULL );
  115.         }
  116.  
  117.         if ( current.st_dev == dir_entry.st_dev  &&
  118.              current.st_ino == dir_entry.st_ino )
  119.         found = 1;
  120.         }
  121.     }
  122.  
  123.     close( fd );
  124.  
  125.     if ( ! found )
  126.         return( NULL );
  127.  
  128.     if ( strlen(path) + DIRSIZ + 1 > PATH_MAX )
  129.     {
  130.     errno = ERANGE;
  131.     return( NULL );
  132.     }
  133.  
  134.     strcat( path, "/" );
  135.     strncat( path, d.d_name, DIRSIZ );
  136.  
  137.     current.st_dev = parent.st_dev;
  138.     current.st_ino = parent.st_ino;
  139.     }
  140.  
  141.  
  142.   /*  Copy the reversed path name into <buffer>  */
  143.  
  144.   if ( strlen(path) + 1 > size )
  145.     {
  146.     errno = ERANGE;
  147.     return( NULL );
  148.     }
  149.  
  150.   if ( strlen(path) == 0 )
  151.     {
  152.     strcpy( buffer, "/" );
  153.     return( buffer );
  154.     }
  155.  
  156.   *buffer = '\0';
  157.  
  158.   {
  159.   char *r;
  160.  
  161.   while ( (r = rindex( path, '/' )) != NULL )
  162.     {
  163.     strcat( buffer, r );
  164.     *r = '\0';
  165.     }
  166.   }
  167.  
  168.   return( chdir( buffer ) ? NULL : buffer );
  169.   }
  170.  
  171. /* char *getwd(path)
  172.  * char *path;
  173.  * fill CWD in path, returns path
  174.  * on error return NULL with error string in path
  175.  */
  176.  
  177. extern int sys_nerr;
  178. extern char *sys_errlist[];
  179.  
  180. char *getwd(path)
  181. char *path;
  182. {
  183.     register char *p;
  184.  
  185.     if((p = getcwd(path, PATH_MAX)) == (char *)NULL)
  186.     {
  187.     if(path != (char *)NULL)
  188.     {
  189.         if(errno < 0 || errno >= sys_nerr)
  190.         strcpy(path, "Invalid Error");
  191.         else
  192.         strcpy(path, sys_errlist[errno]);
  193.     }
  194.     }
  195.     return p;
  196. }
  197.